    /*author: Sean Shen
	 *plugin-name: quickly validate
	  Version: 1.0.7

	示范
	$("form").Qvalidate();

	<input type="text" placeholder="必填"  valid='{"required":true}'>
	<input type="text" placeholder="邮箱"  valid='{"email":true}'>
	<input type="text" placeholder="必填 邮箱"  valid='{"required":true,"email":true}'>
	<input type="text" placeholder="数字"  valid='{"number":true}'>
    <input type="text" class="input"  name="verifyCode" placeholder="验证码" valid='{"required":true,"limitLength":4,"ajax":{"url":"book-doctor-finish.php","inputName":["cellphone","real_name"],"data":"a=b"}}' />	         //服务器返回json格式 {"result":true,"errorMsg":"无"}

	<input type="text" class="input-text input-text-pos website" placeholder="英文或数字（小于20位）" name='doctor[domain_prefix]' maxlength="20" value="{$doctor.domain_prefix}" valid='{"required":true,"regex":"/^\d+(\.\d{0,2}){0,1}$/"}' msg='{"required":"请填写您想要的域名","regex":"只能包含英文和数字"}'/>

	*/



	$.fn.Qvalidate = function(options){

		var defaults={
			firstError:function(element){//第一个验证不通过处
			  // element.focus();
			  // $("body").animate({ scrollTop: element.offset().top }, 0);

			},
			onError:function(element,msg){//出错回调
			       $(element).addClass("input-error");
				   if($(element)[0].tagName=='SELECT'){
					   //错误控件为select2时处理
                      $(element).next().find(".select2-selection").addClass("input-error");
				   };
				   if($(element).attr('contenteditable')){
					   //错误控件为contenteditable时处理
					  $(element).prev().addClass("input-error");
				   };

			},
			onSuccess:function(element,msg){//成功回调
			       $(element).removeClass("input-error");
				   if($(element)[0].tagName=='SELECT'){
					   //错误控件为select2时处理
					  $(element).next().find(".select2-selection").removeClass("input-error");
				   };
				   if($(element).attr('contenteditable')){
					   //错误控件为contenteditable时处理
					  $(element).prev().removeClass("input-error");
				   }


			},
			ignore:"" //传字符串用逗号分隔

		};
		var options = $.extend(defaults, options);

//		if(options){
//			$.extend(defaults,options);
//		};
		var formObj = this;
		var elements = this.find("input:enabled,select:enabled,textarea:enabled,[contenteditable]:enabled").not($(options.ignore));

		//递交表单时验证
        $(this).bind('submit', validateAll)


		//验证表单所有控件
		function validateAll(){

			//console.log(formObj)
			var allResult=true;
			var firstError=false;
			//$.each( elements, function(id, element){
				/**
				 * 2015.7.2
				 */
			for(var a=0;a<elements.length;a++){

				//for(var a=elements.length-1;a>-1;a--){
				if (eval("(" +$(elements[a]).attr("valid")+ ")")){//判断是否需要验证该元素

					var method =  eval("(" +$(elements[a]).attr("valid")+ ")");  //获取验证规则
					var errorMsg =  eval("(" +$(elements[a]).attr("msg")+ ")"); //获取验证错误消息

				    //console.log(errorMsg);
					//console.log(validate($(element),method,errorMsg))
					if($(elements[a]).attr("type")=="checkbox"){
						//判断当checkbox时特殊处理

						if(method.required==true){
							chkResult=false;
							//console.log($("[type='checkbox'][name="+$(elements[a]).attr("name")+"]").prop("checked"));
							$.each( $("[type='checkbox'][name='"+$(elements[a]).attr("name")+"']"), function(id, element){
								 if($(element).prop("checked")){
									chkResult=true;
								 }
							});
							if(chkResult==false){
								allResult=false;
								options.onError(elements[a],errorMsg.required);

							};
						};
						//console.log(allResult);

					}else{
						if(validate($(elements[a]),method,errorMsg,options)===false){//验证不通过时返回false
							  if(firstError===false){firstError=$(elements[a])} //取得第一个验证不通过的控件
							  allResult=false;
						};
					}

				};
			}
			 //});

			//滑到第一个错误处触发回调函数
			if(firstError){
				options.firstError(firstError);
			}



			return allResult;


		}


		//单独方法用于返回验证结果
		$.fn.Qvalidate.valid=validateAll;

		//获取需要验证的元素
		//var elements=$(this).find("input,select,textarea");
		//单个控件触发事件时验证
		elements.each(function(){
			if ($(this).attr("valid")){//判断是否需要验证该元素
			   var method = eval("(" +$(this).attr("valid")+ ")");
			   var errorMsg = eval("(" +$(this).attr("msg")+ ")"); //获取验证错误消息
			   if($(this).attr('contenteditable')){

					//div编辑器时特殊处理
					 var target = this;
					 Object.defineProperty(target,'_value',{
						   set:function(v){
							   this.value=v;
							   validate($(target),method,errorMsg,options);
						   }
					 });
					 //$(this).on('change',function(){
					 //	validate($(this).siblings('input'),method,errorMsg);//验证元素
					 //})
			   }else if($(this).attr('tabindex')){
			   	    //select2 时的绑定
					$(this).bind('change', {el:$(this), method:method, errorMsg:errorMsg,settings:options},validateEvent);
			   }else if(!$(this).attr('tabindex')){
			   	    //非select2 时的绑定

			   	    $(this).bind('change blur focus', {el:$(this), method:method, errorMsg:errorMsg,settings:options},validateEvent);
			   }


			}


    	});


		// function destory(){
		// 	formObj.unbind('submit');
		// 	formObj.find("input,select,textarea,[contenteditable]").unbind('change select2-selecting blur focus',validateEvent);
		// 	$(".input-error").removeClass("input-error");
		// }
		// return {
		// 	destory:destory
		// }
    };

	//销毁方法
	$.fn.QvalidateDestory=function(){

		this.unbind('submit');
		var elements = this.find("input,select,textarea,[contenteditable]");
		elements.each(function(){

			elements.unbind('change blur focus',validateEvent);

		});
		$(".input-error").removeClass("input-error");


	}

	function validateEvent(e){

		validate(e.data.el, e.data.method, e.data.errorMsg,e.data.settings);
	}
	//具体验证方法
	function validate(element,method,msg,settings){

        settings.onSuccess(element);//去除所有错误效果
        var result = new Array(); //result数组存放每个验证规则的结果

		for (var key in method ){

			  var rule=method[key]; //验证规则


			  switch(key.toLowerCase()){

				  case "required":  //验证必填


				      msg==null ? errorMsg = "" : errorMsg = msg.required;  //验证错误消息为null时,设为空值

					  if(element.attr("type")== "checkbox"){  //验证控件是checkbox

						 if(element[0].checked==true){
							settings.onSuccess(element,errorMsg);
						    result[key] = true;
					     }else{
							settings.onError(element,errorMsg);
							result[key] = false;

							return false;
						 };

					  }else{//验证控件是输入框或下拉选择器

						 if(element.val() || element.attr("checked")== true){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;

						 }else{//验证失败

							  settings.onError(element,errorMsg);
							  result[key] = false;

							  return false;
						 }



					  }



					  break;
				  case "email":  //验证邮件格式

					  msg==null ? errorMsg = "" : errorMsg = msg.email;  //验证错误消息为null时,设为空值
				      if(element.val()){
						  if (element.val().search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;
				  case "minlength":

					  msg==null ? errorMsg = "" : errorMsg = msg.minLength;  //验证错误消息为null时,设为空值

				      if(element.val()){
						  if (element.val().length>=rule){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;
				  case "maxlength":

					  msg==null ? errorMsg = "" : errorMsg = msg.maxLength;  //验证错误消息为null时,设为空值

				      if(element.val()){
						  if (element.val().length<=rule){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;
				  case "limitlength":

					  msg==null ? errorMsg = "" : errorMsg = msg.limitLength;  //验证错误消息为null时,设为空值

				      if(element.val()){
						  if (element.val().length==rule){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;

							  return false;
						  }
					  }
					  break;
				  case "number":   //整数

					  msg==null ? errorMsg = "" : errorMsg = msg.number;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (element.val().search(/^[0-9]+$/) != -1){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;

				  case "gt":   //大于

					  msg==null ? errorMsg = "" : errorMsg = msg.gt;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (parseInt(element.val()) > parseInt(rule)){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;

				  case "egt":   //大等于

					  msg==null ? errorMsg = "" : errorMsg = msg.egt;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (parseInt(element.val()) >= parseInt(rule)){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;

				  case "lt":   //小于

					  msg==null ? errorMsg = "" : errorMsg = msg.lt;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (parseInt(element.val()) < parseInt(rule)){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;


				  case "elt":   //小等于

					  msg==null ? errorMsg = "" : errorMsg = msg.elt;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (parseInt(element.val()) <= parseInt(rule)){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{
							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;


				  case "currency":  //货币小数点后2位

					  msg==null ? errorMsg = "" : errorMsg = msg.currency;  //验证错误消息为null时,设为空

				      if(element.val()){
						  // changelog: 更新验证正则为：/^\d+(\.\d{0,2}){0,1}$/，之前为：/^\d+.?\d{0,2}$/
						  if (/^\d+(\.\d{0,2}){0,1}$/.test(element.val())){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;
				  case "currencyFormat":  //货币带逗号分割 支持小数点后2位

					  msg==null ? errorMsg = "" : errorMsg = msg.currency;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (/^([1-9][0-9]{0,2}(,[0-9]{3})*|0)(\.[0-9]{1,2}$)?$/.test(element.val())){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;
				  case "float":

					  msg==null ? errorMsg = "" : errorMsg = msg.float;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (/[1-9]\d*.\d*|0.\d*[1-9]\d*/.test(element.val())){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;

				  case "numberrange":

					  msg==null ? errorMsg = "" : errorMsg = msg.numberRange;  //验证错误消息为null时,设为空

				      if(element.val()){

						  if (element.val()>= rule[0] && element.val()<= rule[1]){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;

				  case "chinese":  //验证中文输入

					  msg==null ? errorMsg = "" : errorMsg = msg.chinese;  //验证错误消息为null时,设为空值
				      if(element.val()){
						  if (element.val().search(/^[\u4E00-\u9FA5]{1,100}$/) != -1){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;

				  case "password":  //验证密码输入

					  msg==null ? errorMsg = "" : errorMsg = msg.password;  //验证错误消息为null时,设为空值
				      if(element.val()){
				      	  var figure = /[\d]/g;
		                  var lower = /[a-z]/g;
		                  var upper = /[A-Z]/g;
						  if (figure.test(element.val()) && lower.test(element.val()) && upper.test(element.val())){
						  //密码包含大小写字母和数字

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;
				  case "equalto":

					  msg==null ? errorMsg = "" : errorMsg = msg.equalTo;  //验证错误消息为null时,设为空

				      if(element.val()){
						  if (element.val()==$(element).parents('form').find(rule).val()){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;

				  case "cellphone":

					  msg==null ? errorMsg = "" : errorMsg = msg.cellphone;  //验证错误消息为null时,设为空

				      if(element.val()){
						  var reg=/^(0|86|17951)?(13[0-9]|15[0-9]|17[0-9]|18[0-9]|14[57])[0-9]{8}$/;
						  if (reg.test(element.val())==true){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;

				  case "residenceid":

					  msg==null ? errorMsg = "" : errorMsg = msg.residenceID;  //验证错误消息为null时,设为空

				      if(element.val()){

						  if (isIdCardNo(element.val())){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }

					  }
					  break;
				  case "regex":  //正则验证

					  msg==null ? errorMsg = "" : errorMsg = msg.regex;  //验证错误消息为null时,设为空值

					  rule=eval(rule);
				      if(element.val()){
						  if (rule.test(element.val())){//验证成功

							  settings.onSuccess(element,errorMsg);
							  result[key] = true;
						  }else{

							  settings.onError(element,errorMsg);
							  result[key] = false;
							  return false;
						  }
					  }
					  break;
				  case "ajax":

					  //返回json格式 {"result":true,"errorMsg":"无"}
					  result[key] = false;

					  //把传参控件转为字符串
					  inputName="";
					  if(rule.inputName){
					  	for(var k in rule.inputName){
					  			if(!isNaN(k)){
					  				//如果key是数字
					  				inputName += rule.inputName[k] +"="+$(element).parents('form').find("input[name='"+rule.inputName[k]+"']").val()+"&";
					  			} else {
					  				//如果是关联数组
					  				inputName += (rule.inputName[k]?rule.inputName[k]:k) +"="+$(element).parents('form').find("input[name='"+k+"']").val()+"&";
					  			}

					  		}
						 //  $.each( rule.inputName, function(i, n){
							// //  alert( "Name: " + i + ", Value: " + n );
							//  inputName+=n +"="+$("input[name='"+n+"']").val()+"&";
						 //  });
					  }
					  //console.log(inputName);
                      if(rule.data){
						  customerData=rule.data;
					  }else{
				     	  customerData="";
					  };



					  $.ajax({
						   type: "GET",
						   async:false,
						   url: rule.url,
						   data: element.attr("name")+"="+element.val()+"&"+inputName+customerData,
						   dataType:"json",
						   success: function(json){
							 	// console.log(json.result)
							  if(json.status==true || json.status=="true"){

								  settings.onSuccess(element,json.msg);
								  result[key] = true;

							  }else{

								  settings.onError(element,json.msg);
								  result[key] = false;
								  return false;

							  }

						   }
					  });

					  //console.log(element.attr("name")+" inside ajax("+key+") -> "+result[key]);
					  break;
				  case "residenceidsex":

					  msg==null ? errorMsg = "" : errorMsg = msg.residenceIDsex;  //验证错误消息为null时,设为

				      if(element.val()){
					  var value=element.val();
							if (value.length === 18) { //判断18位身份证性别
								if (parseInt(value.substr(-3, 2)) % 2 === 0) {
									  settings.onSuccess(element,errorMsg);
									  result[key] = true;
								}else{
									  settings.onError(element,errorMsg);
									  result[key] = false;
									  return false;
								}
							}
							else if (value.length === 15) {//判断15位身份证性别
								if (parseInt(value.substr(-2, 2)) % 2 === 0) {
									  settings.onSuccess(element,errorMsg);
									  result[key] = true;
								}else{
									  settings.onError(element,errorMsg);
									  result[key] = false;
									  return false;
								}
							}

					  }
					  break;
			//		default:
			//      result["default"] = false;


			  }


		};

		// if(element.attr("name") == 'verifyCode' && key == 'ajax'){
	 //  		console.log(element.attr("name")+" ajax rule end -> "+rule);
	 //  	}
		// console.log(result)

		var singleResult=true;
		//将每条验证结果收集到数组后，统一验证最后结果
		for(var name in result){

			  if (result[name]===false){//有一条验证规则不通过，该控件验证结果失败
	           // $(element).data("valid", false);
	           	//console.log(element.attr("name")+" outside  " + name +" -> false");
				singleResult=false;
			  }
		};

		//console.log(singleResult)
		return singleResult;


	}

	//检查身份证函数
	function isIdCardNo(num) {

	 var factorArr = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1);
	 var parityBit=new Array("1","0","X","9","8","7","6","5","4","3","2");
	 var varArray = new Array();
	 var intValue;
	 var lngProduct = 0;
	 var intCheckDigit;
	 var intStrLen = num.length;
	 var idNumber = num;
	   // initialize
		 if ((intStrLen != 15) && (intStrLen != 18)) {

			 return false;
		 }
		 // check and set value
		 for(i=0;i<intStrLen;i++) {
			 varArray[i] = idNumber.charAt(i);
			 if ((varArray[i] < '0' || varArray[i] > '9') && (i != 17)) {

				 return false;
			 } else if (i < 17) {
				 varArray[i] = varArray[i] * factorArr[i];
			 }
		 }

		 if (intStrLen == 18) {
			 //check date
			 var date8 = idNumber.substring(6,14);
			 if (isDate8(date8) == false) {

				return false;
			 }
			 // calculate the sum of the products
			 for(i=0;i<17;i++) {
				 lngProduct = lngProduct + varArray[i];
			 }
			 // calculate the check digit
			 intCheckDigit = parityBit[lngProduct % 11];
			 // check last digit
			 if (varArray[17].toUpperCase() != intCheckDigit) {
				 return false;
			 }
		 }
		 else{        //length is 15
			 //check date
			 var date6 = idNumber.substring(6,12);
			 if (isDate6(date6) == false) {

				 return false;
			 }
		 }
		 return true;

	 }

	function isDate6(sDate) {
	   if(!/^[0-9]{6}$/.test(sDate)) {

		  return false;
	   }
	   var year, month, day;
	   year = "19"+sDate.substring(0, 2);
	   month = sDate.substring(2, 4);
	   if (year < 1700 || year > 2500) return false
	   if (month < 1 || month > 12) return false
	   return true
	}

	function isDate8(sDate) {
	   if(!/^[0-9]{8}$/.test(sDate)) {
		  return false;
	   }
	   var year, month, day;
	   year = sDate.substring(0, 4);
	   month = sDate.substring(4, 6);
	   day = sDate.substring(6, 8);
	   var iaMonthDays = [31,28,31,30,31,30,31,31,30,31,30,31]
	   if (year < 1700 || year > 2500) return false
	   if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) iaMonthDays[1]=29;
	   if (month < 1 || month > 12) return false
	   if (day < 1 || day > iaMonthDays[month - 1]) return false
	   return true
	}